from typing import Dict


def new_board() -> Dict[int, str]:
    """
    Using a dictionary in python to store the board,
    since we are not including all numbers within a given range.
    利用字典来做数据容器，因为我们没有包括给定范围内的所有内容
    """
    return {
        13: "!",
        14: "!",
        15: "!",
        22: "!",
        23: "!",
        24: "!",
        29: "!",
        30: "!",
        31: "!",
        32: "!",
        33: "!",
        34: "!",
        35: "!",
        38: "!",
        39: "!",
        40: "!",
        42: "!",
        43: "!",
        44: "!",
        47: "!",
        48: "!",
        49: "!",
        50: "!",
        51: "!",
        52: "!",
        53: "!",
        58: "!",
        59: "!",
        60: "!",
        67: "!",
        68: "!",
        69: "!",
        41: "O",
    }


def print_instructions() -> None:
    print(
        """
HERE IS THE BOARD:

          !    !    !
         13   14   15

          !    !    !
         22   23   24

!    !    !    !    !    !    !
29   30   31   32   33   34   35

!    !    !    !    !    !    !
38   39   40   41   42   43   44

!    !    !    !    !    !    !
47   48   49   50   51   52   53

          !    !    !
         58   59   60

          !    !    !
         67   68   69

TO SAVE TYPING TIME, A COMPRESSED VERSION OF THE GAME BOARD
WILL BE USED DURING PLAY.  REFER TO THE ABOVE ONE FOR PEG
NUMBERS.  OK, LET'S BEGIN.
    """
    )


def print_board(board: Dict[int, str]) -> None:
    """Prints the boards using indexes in the passed parameter
    使用传递的参数中索引"""
    print(" " * 2 + board[13] + board[14] + board[15])
    print(" " * 2 + board[22] + board[23] + board[24])
    print(
        board[29]
        + board[30]
        + board[31]
        + board[32]
        + board[33]
        + board[34]
        + board[35]
    )
    print(
        board[38]
        + board[39]
        + board[40]
        + board[41]
        + board[42]
        + board[43]
        + board[44]
    )
    print(
        board[47]
        + board[48]
        + board[49]
        + board[50]
        + board[51]
        + board[52]
        + board[53]
    )
    print(" " * 2 + board[58] + board[59] + board[60])
    print(" " * 2 + board[67] + board[68] + board[69])


def play_game() -> None:
    # Create new board
    board = new_board()

    # Main game loop
    while not is_game_finished(board):
        print_board(board)
        while not move(board):
            print("ILLEGAL MOVE! TRY AGAIN 非法搬家，再试一次")

    peg_count = sum(1 for key in board.keys() if board[key] == "!")
    print(f"YOU HAD {str(peg_count)} PEGS REMAINING 钉 剩余")

    if peg_count == 1:
        print("BRAVO! YOU MADE A PERFECT SCORE! 棒！你得了满分")
        print("SAVE THIS PAPER AS A RECORD OF YOUR ACCOMPLISHMENT!保存这篇论文作为你的成就记录")


def move(board: Dict[int, str]) -> bool:
    """Queries the user to move. Returns false if the user puts in an invalid input or move, returns true if the move was successful
    查询要移动的用户，如果用户输入了无效移动，则返回false，如果移动成功，则返回true"""
    # 要求用户输入起始跳动的棋子位置
    start = input("Enter the starting position: ")
    # 如果输入的数据不是数字，return false
    if not start.isdigit():
        return False
    start = int(start)

    # 如果起始位置不在棋盘上或者起始位置不是！（棋子） 返回false
    if start not in board or board[start] != "!":
        return False

    # 要求用户输入一个结束位置
    end = input("Enter the ending position输入结束位置: ")
    # 如果用户输入的数据不是数字，返回false
    if not end.isdigit():
        return False
    end = int(end)

    # 如果如果结束位置不在棋盘上或者结束位置不是0（空缺） 返回false
    if end not in board or board[end] != "O":
        return False

    # 找到中间的棋子在字典里面的位置并且将其替换为0
    middle = (start + end) // 2
    if board[middle] != "!":
        return False

    board[start] = "O"
    board[middle] = "O"
    board[end] = "!"

    return True


def main() -> None:
    print(" " * 33 + "H-I-Q")
    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    print_instructions()
    play_game()


def is_game_finished(board) -> bool:
    """Check all locations and whether or not a move is possible at that location
    检查所有位置以及该位置是否可以移动."""
    for pos in board.keys():
        if board[pos] == "!":
            for space in [1, 9]:
                # Checks if the next location has a peg
                next_to_peg = ((pos + space) in board) and board[pos + space] == "!"
                # Checks both going forward (+ location) or backwards (-location)
                has_movable_space = (
                        pos - space not in board
                        or board[pos - space] != "!"
                        or pos + space * 2 not in board
                        or board[pos + space * 2] != "!"
                )
                if next_to_peg and has_movable_space:
                    return False
    return True


if __name__ == "__main__":
    main()